package thread;

/**
 * 同步块的应用
 * 有效的缩小同步范围可以在保证并发安全的前提下尽可能的提高效率。
 * <p>
 * 语法：
 * synchronized(同步监视器对象){
 * 需要多个线程同步执行的代码片段
 * }
 */
public class SyncDemo2 {
    public static void main(String[] args) {
        Shop shop = new Shop();

        Thread t1 = new Thread("可莉"){
            @Override
            public void run() {
                shop.buy();
            }
        };
        Thread t2 = new Thread("蕾姆"){
            @Override
            public void run() {
                shop.buy();
            }
        };
        Thread t3 = new Thread("苍老师"){
            @Override
            public void run() {
                shop.buy();
            }
        };
        t1.start();
        t2.start();
        t3.start();
    }
}

class Shop {
    /*
        在方法上直接使用synchronized,那么同步监视器是不可选的，就是当前方法的所属对象this
     */
    public  void buy() {
        try {
            Thread t = Thread.currentThread();//获取运行buy的线程

            System.out.println(t.getName() + ":正在挑衣服...");
            Thread.sleep(500);

            /*
                同步块在使用时需要在（）中指定同步监视器对象，该对象可以是任何引用类型的实例，
                只要保证多个需要同步执行改代码块的线程看到的这个对象是”同一个“即可。实际开发
                中可结合具体情况选取。
             */
            synchronized (this){System.out.println(t.getName() + ":正在试衣服...");
                Thread.sleep(500);}

            System.out.println(t.getName() + ":结账离开！");
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}